# class className:
#     """This is a class docstring"""
#     pass

#class内的构造方法是__init__方法，在创建对象的时候会自动调用
#有参构造方法
class Function1:
    def __init__(self, name, age): #构造方法必须要包含self参数
        self.name = name
        self.age = age
        print("This is a constructor1")

    def print_info(self):
        print(f"name: {self.name}, age: {self.age}")

    def print_name(self):
        pass
gest_name = Function1("Tom", 18)

#无参构造方法
class Function2:
    def __init__(self): #构造方法必须要包含self参数
        print("This is a constructor2")

gest_name = Function2()

#让类拥有成员变量
class Function3:
    name = "变量1"
    age = "变量2"
    def __init__(self): #构造方法必须要包含self参数
        print("This is a constructor3")
        print(Function3.name,Function3.age)
Function3.sex="男"
gest3=Function3()
#还可以在外部添加类的对象属性
# gest3.sex="男"
print(Function3.sex)
gest3.sex="男"
print(gest3.sex)

#类可以在self中定义参数
class Function4:
    def __init__(self, name, age): #构造方法必须要包含self参数,self可以说是属于类的实例的
        self.name = name
        self.age = age
        print("This is a constructor4")
        print(self.name, self.age)
    def print_info(self): #类的方法必须要包含self参数
        print(f"name: {self.name}, age: {self.age}")
        print(self.name, self.age)

gest4=Function4("Tom", 18)
gest4.print_info()
# 因为self属于类的实例，所以可以通过实例.变量来访问类的变量
print(gest4.name, gest4.age)

# 类可以对成员变量进行访问限制，在变量名前加两个下划线即可
class Function5:
    __neck="脖子长"
    def __init__(self): #构造方法必须要包含self参数,self可以说是属于类的实例的
        print(Function5.__neck)
    def get_neck(self):
        return self.__neck

gest5=Function5()
print(gest5.get_neck())
# print(gest5.__neck)
# print(Function5.__neck)这两个都是不对的，因为__neck是私有的，不能被外部访问,但是可以通过get_neck方法来访问

#类也可以在self中定义保护属性的变量
class Function6:
    def __init__(self):
        print("This is a constructor6")
        self.__neck="脖子短"
    def get_neck(self):
        return self.__neck

gest6=Function6()
print(gest6.get_neck())


#类可以将方法定义成属性，这样就可以通过实例.方法名来调用方法，而不需要实例.方法名()
#只需要在方法名前加@property注解即可
class Function7:
    def __init__(self):
        print("This is a constructor7")
        self.__neck="脖子短"
    @property
    def get_neck(self):
        return self.__neck

gest7=Function7()
print(gest7.get_neck)


"""
类可以实现继承，例如我设定水果为父类，那么苹果香蕉将为子类
"""
class Fruit:
    color = "绿色"
    def harvest(self,color):
        print("水果可以收获")
        print("水果的颜色是：",color)

class Apple(Fruit):
    color = "红色"
    def __init__(self):
        print("我是苹果")

class Banana(Fruit):
    color = "黄色"
    def __init__(self):
        print("我是香蕉")

#子类可以继承父类的属性和方法
apple = Apple()
banana = Banana()
apple.harvest(apple.color)
banana.harvest(banana.color)

#子类可以重写父类的方法
class Apple(Fruit):
    color = "红色"
    def __init__(self):
        print("我是苹果")
    def harvest(self,color):
        print("苹果可以收获")
        print("苹果的颜色是：",color)

apple = Apple()
apple.harvest(apple.color)



#子类可以显式调用父类的方法
#使用super().父方法名()即可
class Fruit:
    color = "绿色"
    def __init__(self):
        print("我是水果")
    def harvest(self,color):
        print("水果可以收获")
        print("水果的颜色是：",color)

class Apple(Fruit):
    color = "红色"
    def __init__(self):
        print("我是苹果")
        super().__init__() #显式调用父类的方法

apple=Apple()
apple.harvest(apple.color)